#include "menu.h"

#include <stdlib.h>

#include "bt.h"
#include "flash.h"
#include "game.h"
#include "hc05.h"
#include "oled.h"
#include "pic.h"
#include "restore.h"
#include "ws2812.h"

#undef Handler
#define Handler Menu_HandleTypeDef*

#undef handler
#define handler (**(Menu_HandleTypeDef**)&handle)

void Menu_Init(void* handle) {
  // 驱动的初始化也在这里
  Hc_Init();
  Oled_Init();
  Flash_Unlock();

  handler.outo = 0;
  handler.mode = MENU_BEGIN;
  Menu_Reinit(handle);
}

void Menu_Reinit(void* handle) {
  // 初始化bt
  Bt_Init(Menu_M_L, NULL, NULL, Menu_M_O,    // M
          Menu_U_LJ, NULL, Menu_U_LJ, NULL,  // U
          Menu_D_LJ, NULL, Menu_D_LJ, NULL,  // D
          NULL, NULL, NULL, NULL,            // L
          NULL, NULL, NULL, NULL,            // R
          200);
  // 初始化WS2812
  Ws_Init();
  // 初始化menu
  handler.into = 0;
  Menu_InitShow();
  turn = 0xFF;
  Menu_ShowLine(handle);
  turn = 0x00;
  // 死循环, 直到所有按键松开
  while (hbt.bu & BU_M) Bt_Update();
}
void Menu_InitShow(void) {
  Oled_ClearAll();
  turn = 0xFF;
  Oled_ShowStringBig(0, 0, "      Menu      ");

  turn = 0x00;
  Oled_ShowStringSmall(0, 2, "Picture");
  Oled_ShowStringSmall(0, 3, "Game");
  Oled_ShowStringSmall(0, 4, "Restore Pictures");
  Oled_ShowStringSmall(0, 5, "Restore Game");
  turn = 0xFF;
  Oled_ShowStringBig(0, 0, "  ");
  turn = 0x00;
}

void Menu_ShowLine(void* handle) {
  switch (handler.mode) {
    case MENU_PICTURE:
      Oled_ShowStringSmall(0, 2, "Picture");
      break;
    case MENU_GAME:
      Oled_ShowStringSmall(0, 3, "Game");
      break;
    case MENU_RESTORE_PIC:
      Oled_ShowStringSmall(0, 4, "Restore Pictures");
      break;
    case MENU_RESTORE_GAME:
      Oled_ShowStringSmall(0, 5, "Restore Game");
  }
}
void Menu_Run(void* handle) {
  while (1) {
    Bt_Update();
    Bt_Run(handle);
    // 判断是否进入子页面
    if (handler.into) {
      switch (handler.mode) {
        case MENU_PICTURE: {
          // 声明子页面的句柄, (若需要则)初始化
          Pic_HandleTypeDef hpic;
          // 输出信息到子页面
          // 子页面初始化
          Pic_Init(&hpic);
          // 子页面运行
          Pic_Run(&hpic);
          // 从子页面获取信息
          ;
        } break;
        case MENU_GAME: {
          Game_HandleTypeDef hgame;
          Game_Init(&hgame);
          Game_Run(&hgame);
        } break;
        case MENU_RESTORE_PIC:
          Oled_ClearAll();
          Restore_ResPic();
          break;
        case MENU_RESTORE_GAME:
          Oled_ClearAll();
          Restore_ResGame();
          break;
      }
      Menu_Reinit(handle);
    }
    // 判断是否退出当前页面
    if (handler.outo) {
      return;
    }
  }
}

void Menu_M_L(void* handle) {
  handler.outo = 1;
  Ws_Init();
  Oled_ClearAll();
}
// M键的点击任务只能被当最O型执行, 否则会覆盖M键的长按任务,
// 因为M键点击之后就进入子页面了, 跳转到子页面的Run函数,
// 而此页面的长按任务自然无法执行
void Menu_M_O(void* handle) { handler.into = 1; }
void Menu_U_LJ(void* handle) {
  Menu_ShowLine(handle);
  if (handler.mode > MENU_BEGIN) {
    handler.mode--;
  } else {
    handler.mode = MENU_END;
  }
  turn = 0xFF;
  Menu_ShowLine(handle);
  turn = 0x00;
}
void Menu_D_LJ(void* handle) {
  Menu_ShowLine(handle);
  if (handler.mode < MENU_END) {
    handler.mode++;
  } else {
    handler.mode = MENU_BEGIN;
  }
  turn = 0xFF;
  Menu_ShowLine(handle);
  turn = 0x00;
}
